//=======================================================================================
// Box.cpp by Frank Luna (C) 2008 All Rights Reserved.
//=======================================================================================

#include "Game Engine/Header/Box.h"

Box::Box()
: mNumVertices(0), mNumFaces(0), md3dDevice(0), mVB(0), mIB(0)
{
}
 
Box::~Box()
{
	ReleaseCOM(mVB);
	ReleaseCOM(mIB);
}

void Box::init(ID3D10Device* device, D3DXVECTOR3 size, float scale)
{
	md3dDevice = device;

	mNumVertices = 24;
	mNumFaces    = 12; // 2 per quad

	// Fill in the front face vertex data.
	mVertices.push_back( Vertex( -size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f,  size.y / 2.0f, -size.z / 2.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f,  size.y / 2.0f, -size.z / 2.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f));
						 
	// Fill in the back face vertex data.
	mVertices.push_back( Vertex( -size.x / 2.0f, -size.y / 2.0f,  size.z / 2.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f, -size.y / 2.0f,  size.z / 2.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f,  size.y / 2.0f,  size.z / 2.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f,  size.y / 2.0f,  size.z / 2.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f));

	// Fill in the top face vertex data.
	mVertices.push_back( Vertex( -size.x / 2.0f,  size.y / 2.0f, -size.z / 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f,  size.y / 2.0f,  size.z / 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f,  size.y / 2.0f,  size.z / 2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f,  size.y / 2.0f, -size.z / 2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f));

	// Fill in the bottom face vertex data.
	mVertices.push_back( Vertex( -size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f, -size.y / 2.0f,  size.z / 2.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f, -size.y / 2.0f,  size.z / 2.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f));

	// Fill in the left face vertex data.
	mVertices.push_back( Vertex( -size.x / 2.0f, -size.y / 2.0f,  size.z / 2.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f,  size.y / 2.0f,  size.z / 2.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f,  size.y / 2.0f, -size.z / 2.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f));
	mVertices.push_back( Vertex( -size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f));

	// Fill in the right face vertex data.
	mVertices.push_back( Vertex(  size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f,  size.y / 2.0f, -size.z / 2.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f,  size.y / 2.0f,  size.z / 2.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f));
	mVertices.push_back( Vertex(  size.x / 2.0f, -size.y / 2.0f,  size.z / 2.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f));

	// Scale the box.
	for(DWORD i = 0; i < mNumVertices; ++i)
		mVertices[i].pos *= scale;

    D3D10_BUFFER_DESC vbd;
    vbd.Usage = D3D10_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(Vertex) * mNumVertices;
    vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = &mVertices[0];
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB));


	// Fill in the front face index data
	mIndices.push_back(0); mIndices.push_back(1); mIndices.push_back(2);
	mIndices.push_back(0); mIndices.push_back(2); mIndices.push_back(3);

	// Fill in the back index data
	mIndices.push_back(4); mIndices.push_back(5); mIndices.push_back(6);
	mIndices.push_back(4); mIndices.push_back(6); mIndices.push_back(7);

	// Fill in the top index data
	mIndices.push_back(8); mIndices.push_back(9); mIndices.push_back(10);
	mIndices.push_back(8); mIndices.push_back(10); mIndices.push_back(11);

	// Fill in the botte index data
	mIndices.push_back(12); mIndices.push_back(13); mIndices.push_back(14);
	mIndices.push_back(12); mIndices.push_back(14); mIndices.push_back(15);

	// Fill in the leftindex data
	mIndices.push_back(16); mIndices.push_back(17); mIndices.push_back(18);
	mIndices.push_back(16); mIndices.push_back(18); mIndices.push_back(19);

	// Fill in the righ index data
	mIndices.push_back(20); mIndices.push_back(21); mIndices.push_back(22);
	mIndices.push_back(20); mIndices.push_back(22); mIndices.push_back(23);

	D3D10_BUFFER_DESC ibd;
    ibd.Usage = D3D10_USAGE_IMMUTABLE;
	ibd.ByteWidth = sizeof(DWORD) * mNumFaces*3;
    ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = &mIndices[0];
    HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));
}

void Box::draw()
{
	UINT stride = sizeof(Vertex);
    UINT offset = 0;
    md3dDevice->IASetVertexBuffers(0, 1, &mVB, &stride, &offset);
	md3dDevice->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0);
	md3dDevice->DrawIndexed(mNumFaces*3, 0, 0);
}

std::vector<Vertex> Box::GetVertices()
{
	return mVertices;
}

std::vector<DWORD> Box::GetIndices()
{
	return mIndices;
}